// Copyright (c) Lawrence Livermore National Security, LLC and other VisIt
// Project developers.  See the top-level LICENSE file for dates and other
// details.  No copyright assignment is required to contribute to VisIt.

#include <AnnotationAttributes.h>
#include <DataNode.h>

//
// Enum conversion methods for AnnotationAttributes::GradientStyle
//

static const char *GradientStyle_strings[] = {
"TopToBottom", "BottomToTop", "LeftToRight",
"RightToLeft", "Radial"};

std::string
AnnotationAttributes::GradientStyle_ToString(AnnotationAttributes::GradientStyle t)
{
    int index = int(t);
    if(index < 0 || index >= 5) index = 0;
    return GradientStyle_strings[index];
}

std::string
AnnotationAttributes::GradientStyle_ToString(int t)
{
    int index = (t < 0 || t >= 5) ? 0 : t;
    return GradientStyle_strings[index];
}

bool
AnnotationAttributes::GradientStyle_FromString(const std::string &s, AnnotationAttributes::GradientStyle &val)
{
    val = AnnotationAttributes::TopToBottom;
    for(int i = 0; i < 5; ++i)
    {
        if(s == GradientStyle_strings[i])
        {
            val = (GradientStyle)i;
            return true;
        }
    }
    return false;
}

//
// Enum conversion methods for AnnotationAttributes::BackgroundMode
//

static const char *BackgroundMode_strings[] = {
"Solid", "Gradient", "Image",
"ImageSphere"};

std::string
AnnotationAttributes::BackgroundMode_ToString(AnnotationAttributes::BackgroundMode t)
{
    int index = int(t);
    if(index < 0 || index >= 4) index = 0;
    return BackgroundMode_strings[index];
}

std::string
AnnotationAttributes::BackgroundMode_ToString(int t)
{
    int index = (t < 0 || t >= 4) ? 0 : t;
    return BackgroundMode_strings[index];
}

bool
AnnotationAttributes::BackgroundMode_FromString(const std::string &s, AnnotationAttributes::BackgroundMode &val)
{
    val = AnnotationAttributes::Solid;
    for(int i = 0; i < 4; ++i)
    {
        if(s == BackgroundMode_strings[i])
        {
            val = (BackgroundMode)i;
            return true;
        }
    }
    return false;
}

//
// Enum conversion methods for AnnotationAttributes::PathExpansionMode
//

static const char *PathExpansionMode_strings[] = {
"File", "Directory", "Full",
"Smart", "SmartDirectory"};

std::string
AnnotationAttributes::PathExpansionMode_ToString(AnnotationAttributes::PathExpansionMode t)
{
    int index = int(t);
    if(index < 0 || index >= 5) index = 0;
    return PathExpansionMode_strings[index];
}

std::string
AnnotationAttributes::PathExpansionMode_ToString(int t)
{
    int index = (t < 0 || t >= 5) ? 0 : t;
    return PathExpansionMode_strings[index];
}

bool
AnnotationAttributes::PathExpansionMode_FromString(const std::string &s, AnnotationAttributes::PathExpansionMode &val)
{
    val = AnnotationAttributes::File;
    for(int i = 0; i < 5; ++i)
    {
        if(s == PathExpansionMode_strings[i])
        {
            val = (PathExpansionMode)i;
            return true;
        }
    }
    return false;
}

// ****************************************************************************
// Method: AnnotationAttributes::AnnotationAttributes
//
// Purpose:
//   Init utility for the AnnotationAttributes class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

void AnnotationAttributes::Init()
{
    userInfoFlag = true;
    databaseInfoFlag = true;
    timeInfoFlag = true;
    databaseInfoExpansionMode = File;
    databaseInfoTimeScale = 1;
    databaseInfoTimeOffset = 0;
    legendInfoFlag = true;
    gradientBackgroundStyle = Radial;
    backgroundMode = Solid;
    imageRepeatX = 1;
    imageRepeatY = 1;

    AnnotationAttributes::SelectAll();
}

// ****************************************************************************
// Method: AnnotationAttributes::AnnotationAttributes
//
// Purpose:
//   Copy utility for the AnnotationAttributes class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

void AnnotationAttributes::Copy(const AnnotationAttributes &obj)
{
    axes2D = obj.axes2D;
    axes3D = obj.axes3D;
    userInfoFlag = obj.userInfoFlag;
    userInfoFont = obj.userInfoFont;
    databaseInfoFlag = obj.databaseInfoFlag;
    timeInfoFlag = obj.timeInfoFlag;
    databaseInfoFont = obj.databaseInfoFont;
    databaseInfoExpansionMode = obj.databaseInfoExpansionMode;
    databaseInfoTimeScale = obj.databaseInfoTimeScale;
    databaseInfoTimeOffset = obj.databaseInfoTimeOffset;
    legendInfoFlag = obj.legendInfoFlag;
    backgroundColor = obj.backgroundColor;
    foregroundColor = obj.foregroundColor;
    gradientBackgroundStyle = obj.gradientBackgroundStyle;
    gradientColor1 = obj.gradientColor1;
    gradientColor2 = obj.gradientColor2;
    backgroundMode = obj.backgroundMode;
    backgroundImage = obj.backgroundImage;
    imageRepeatX = obj.imageRepeatX;
    imageRepeatY = obj.imageRepeatY;
    axesArray = obj.axesArray;

    AnnotationAttributes::SelectAll();
}

// Type map format string
const char *AnnotationAttributes::TypeMapFormatString = ANNOTATIONATTRIBUTES_TMFS;
const AttributeGroup::private_tmfs_t AnnotationAttributes::TmfsStruct = {ANNOTATIONATTRIBUTES_TMFS};


// ****************************************************************************
// Method: AnnotationAttributes::AnnotationAttributes
//
// Purpose:
//   Default constructor for the AnnotationAttributes class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

AnnotationAttributes::AnnotationAttributes() :
    AttributeSubject(AnnotationAttributes::TypeMapFormatString),
    backgroundColor(255, 255, 255), foregroundColor(0, 0, 0),
    gradientColor1(0, 0, 255), gradientColor2(0, 0, 0)
{
    AnnotationAttributes::Init();
}

// ****************************************************************************
// Method: AnnotationAttributes::AnnotationAttributes
//
// Purpose:
//   Constructor for the derived classes of AnnotationAttributes class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

AnnotationAttributes::AnnotationAttributes(private_tmfs_t tmfs) :
    AttributeSubject(tmfs.tmfs),
    backgroundColor(255, 255, 255), foregroundColor(0, 0, 0),
    gradientColor1(0, 0, 255), gradientColor2(0, 0, 0)
{
    AnnotationAttributes::Init();
}

// ****************************************************************************
// Method: AnnotationAttributes::AnnotationAttributes
//
// Purpose:
//   Copy constructor for the AnnotationAttributes class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

AnnotationAttributes::AnnotationAttributes(const AnnotationAttributes &obj) :
    AttributeSubject(AnnotationAttributes::TypeMapFormatString)
{
    AnnotationAttributes::Copy(obj);
}

// ****************************************************************************
// Method: AnnotationAttributes::AnnotationAttributes
//
// Purpose:
//   Copy constructor for derived classes of the AnnotationAttributes class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

AnnotationAttributes::AnnotationAttributes(const AnnotationAttributes &obj, private_tmfs_t tmfs) :
    AttributeSubject(tmfs.tmfs)
{
    AnnotationAttributes::Copy(obj);
}

// ****************************************************************************
// Method: AnnotationAttributes::~AnnotationAttributes
//
// Purpose:
//   Destructor for the AnnotationAttributes class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

AnnotationAttributes::~AnnotationAttributes()
{
    // nothing here
}

// ****************************************************************************
// Method: AnnotationAttributes::operator =
//
// Purpose:
//   Assignment operator for the AnnotationAttributes class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

AnnotationAttributes&
AnnotationAttributes::operator = (const AnnotationAttributes &obj)
{
    if (this == &obj) return *this;

    AnnotationAttributes::Copy(obj);

    return *this;
}

// ****************************************************************************
// Method: AnnotationAttributes::operator ==
//
// Purpose:
//   Comparison operator == for the AnnotationAttributes class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

bool
AnnotationAttributes::operator == (const AnnotationAttributes &obj) const
{
    // Create the return value
    return ((axes2D == obj.axes2D) &&
            (axes3D == obj.axes3D) &&
            (userInfoFlag == obj.userInfoFlag) &&
            (userInfoFont == obj.userInfoFont) &&
            (databaseInfoFlag == obj.databaseInfoFlag) &&
            (timeInfoFlag == obj.timeInfoFlag) &&
            (databaseInfoFont == obj.databaseInfoFont) &&
            (databaseInfoExpansionMode == obj.databaseInfoExpansionMode) &&
            (databaseInfoTimeScale == obj.databaseInfoTimeScale) &&
            (databaseInfoTimeOffset == obj.databaseInfoTimeOffset) &&
            (legendInfoFlag == obj.legendInfoFlag) &&
            (backgroundColor == obj.backgroundColor) &&
            (foregroundColor == obj.foregroundColor) &&
            (gradientBackgroundStyle == obj.gradientBackgroundStyle) &&
            (gradientColor1 == obj.gradientColor1) &&
            (gradientColor2 == obj.gradientColor2) &&
            (backgroundMode == obj.backgroundMode) &&
            (backgroundImage == obj.backgroundImage) &&
            (imageRepeatX == obj.imageRepeatX) &&
            (imageRepeatY == obj.imageRepeatY) &&
            (axesArray == obj.axesArray));
}

// ****************************************************************************
// Method: AnnotationAttributes::operator !=
//
// Purpose:
//   Comparison operator != for the AnnotationAttributes class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

bool
AnnotationAttributes::operator != (const AnnotationAttributes &obj) const
{
    return !(this->operator == (obj));
}

// ****************************************************************************
// Method: AnnotationAttributes::TypeName
//
// Purpose:
//   Type name method for the AnnotationAttributes class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

const std::string
AnnotationAttributes::TypeName() const
{
    return "AnnotationAttributes";
}

// ****************************************************************************
// Method: AnnotationAttributes::CopyAttributes
//
// Purpose:
//   CopyAttributes method for the AnnotationAttributes class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

bool
AnnotationAttributes::CopyAttributes(const AttributeGroup *atts)
{
    if(TypeName() != atts->TypeName())
        return false;

    // Call assignment operator.
    const AnnotationAttributes *tmp = (const AnnotationAttributes *)atts;
    *this = *tmp;

    return true;
}

// ****************************************************************************
// Method: AnnotationAttributes::CreateCompatible
//
// Purpose:
//   CreateCompatible method for the AnnotationAttributes class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

AttributeSubject *
AnnotationAttributes::CreateCompatible(const std::string &tname) const
{
    AttributeSubject *retval = 0;
    if(TypeName() == tname)
        retval = new AnnotationAttributes(*this);
    // Other cases could go here too.

    return retval;
}

// ****************************************************************************
// Method: AnnotationAttributes::NewInstance
//
// Purpose:
//   NewInstance method for the AnnotationAttributes class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

AttributeSubject *
AnnotationAttributes::NewInstance(bool copy) const
{
    AttributeSubject *retval = 0;
    if(copy)
        retval = new AnnotationAttributes(*this);
    else
        retval = new AnnotationAttributes;

    return retval;
}

// ****************************************************************************
// Method: AnnotationAttributes::SelectAll
//
// Purpose:
//   Selects all attributes.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

void
AnnotationAttributes::SelectAll()
{
    Select(ID_axes2D,                    (void *)&axes2D);
    Select(ID_axes3D,                    (void *)&axes3D);
    Select(ID_userInfoFlag,              (void *)&userInfoFlag);
    Select(ID_userInfoFont,              (void *)&userInfoFont);
    Select(ID_databaseInfoFlag,          (void *)&databaseInfoFlag);
    Select(ID_timeInfoFlag,              (void *)&timeInfoFlag);
    Select(ID_databaseInfoFont,          (void *)&databaseInfoFont);
    Select(ID_databaseInfoExpansionMode, (void *)&databaseInfoExpansionMode);
    Select(ID_databaseInfoTimeScale,     (void *)&databaseInfoTimeScale);
    Select(ID_databaseInfoTimeOffset,    (void *)&databaseInfoTimeOffset);
    Select(ID_legendInfoFlag,            (void *)&legendInfoFlag);
    Select(ID_backgroundColor,           (void *)&backgroundColor);
    Select(ID_foregroundColor,           (void *)&foregroundColor);
    Select(ID_gradientBackgroundStyle,   (void *)&gradientBackgroundStyle);
    Select(ID_gradientColor1,            (void *)&gradientColor1);
    Select(ID_gradientColor2,            (void *)&gradientColor2);
    Select(ID_backgroundMode,            (void *)&backgroundMode);
    Select(ID_backgroundImage,           (void *)&backgroundImage);
    Select(ID_imageRepeatX,              (void *)&imageRepeatX);
    Select(ID_imageRepeatY,              (void *)&imageRepeatY);
    Select(ID_axesArray,                 (void *)&axesArray);
}

///////////////////////////////////////////////////////////////////////////////
// Persistence methods
///////////////////////////////////////////////////////////////////////////////

// ****************************************************************************
// Method: AnnotationAttributes::CreateNode
//
// Purpose:
//   This method creates a DataNode representation of the object so it can be saved to a config file.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

bool
AnnotationAttributes::CreateNode(DataNode *parentNode, bool completeSave, bool forceAdd)
{
    if(parentNode == 0)
        return false;

    AnnotationAttributes defaultObject;
    bool addToParent = false;
    // Create a node for AnnotationAttributes.
    DataNode *node = new DataNode("AnnotationAttributes");

    if(completeSave || !FieldsEqual(ID_axes2D, &defaultObject))
    {
        DataNode *axes2DNode = new DataNode("axes2D");
        if(axes2D.CreateNode(axes2DNode, completeSave, false))
        {
            addToParent = true;
            node->AddNode(axes2DNode);
        }
        else
            delete axes2DNode;
    }

    if(completeSave || !FieldsEqual(ID_axes3D, &defaultObject))
    {
        DataNode *axes3DNode = new DataNode("axes3D");
        if(axes3D.CreateNode(axes3DNode, completeSave, false))
        {
            addToParent = true;
            node->AddNode(axes3DNode);
        }
        else
            delete axes3DNode;
    }

    if(completeSave || !FieldsEqual(ID_userInfoFlag, &defaultObject))
    {
        addToParent = true;
        node->AddNode(new DataNode("userInfoFlag", userInfoFlag));
    }

    if(completeSave || !FieldsEqual(ID_userInfoFont, &defaultObject))
    {
        DataNode *userInfoFontNode = new DataNode("userInfoFont");
        if(userInfoFont.CreateNode(userInfoFontNode, completeSave, false))
        {
            addToParent = true;
            node->AddNode(userInfoFontNode);
        }
        else
            delete userInfoFontNode;
    }

    if(completeSave || !FieldsEqual(ID_databaseInfoFlag, &defaultObject))
    {
        addToParent = true;
        node->AddNode(new DataNode("databaseInfoFlag", databaseInfoFlag));
    }

    if(completeSave || !FieldsEqual(ID_timeInfoFlag, &defaultObject))
    {
        addToParent = true;
        node->AddNode(new DataNode("timeInfoFlag", timeInfoFlag));
    }

    if(completeSave || !FieldsEqual(ID_databaseInfoFont, &defaultObject))
    {
        DataNode *databaseInfoFontNode = new DataNode("databaseInfoFont");
        if(databaseInfoFont.CreateNode(databaseInfoFontNode, completeSave, false))
        {
            addToParent = true;
            node->AddNode(databaseInfoFontNode);
        }
        else
            delete databaseInfoFontNode;
    }

    if(completeSave || !FieldsEqual(ID_databaseInfoExpansionMode, &defaultObject))
    {
        addToParent = true;
        node->AddNode(new DataNode("databaseInfoExpansionMode", PathExpansionMode_ToString(databaseInfoExpansionMode)));
    }

    if(completeSave || !FieldsEqual(ID_databaseInfoTimeScale, &defaultObject))
    {
        addToParent = true;
        node->AddNode(new DataNode("databaseInfoTimeScale", databaseInfoTimeScale));
    }

    if(completeSave || !FieldsEqual(ID_databaseInfoTimeOffset, &defaultObject))
    {
        addToParent = true;
        node->AddNode(new DataNode("databaseInfoTimeOffset", databaseInfoTimeOffset));
    }

    if(completeSave || !FieldsEqual(ID_legendInfoFlag, &defaultObject))
    {
        addToParent = true;
        node->AddNode(new DataNode("legendInfoFlag", legendInfoFlag));
    }

        DataNode *backgroundColorNode = new DataNode("backgroundColor");
        if(backgroundColor.CreateNode(backgroundColorNode, completeSave, true))
        {
            addToParent = true;
            node->AddNode(backgroundColorNode);
        }
        else
            delete backgroundColorNode;
        DataNode *foregroundColorNode = new DataNode("foregroundColor");
        if(foregroundColor.CreateNode(foregroundColorNode, completeSave, true))
        {
            addToParent = true;
            node->AddNode(foregroundColorNode);
        }
        else
            delete foregroundColorNode;
    if(completeSave || !FieldsEqual(ID_gradientBackgroundStyle, &defaultObject))
    {
        addToParent = true;
        node->AddNode(new DataNode("gradientBackgroundStyle", GradientStyle_ToString(gradientBackgroundStyle)));
    }

        DataNode *gradientColor1Node = new DataNode("gradientColor1");
        if(gradientColor1.CreateNode(gradientColor1Node, completeSave, true))
        {
            addToParent = true;
            node->AddNode(gradientColor1Node);
        }
        else
            delete gradientColor1Node;
        DataNode *gradientColor2Node = new DataNode("gradientColor2");
        if(gradientColor2.CreateNode(gradientColor2Node, completeSave, true))
        {
            addToParent = true;
            node->AddNode(gradientColor2Node);
        }
        else
            delete gradientColor2Node;
    if(completeSave || !FieldsEqual(ID_backgroundMode, &defaultObject))
    {
        addToParent = true;
        node->AddNode(new DataNode("backgroundMode", BackgroundMode_ToString(backgroundMode)));
    }

    if(completeSave || !FieldsEqual(ID_backgroundImage, &defaultObject))
    {
        addToParent = true;
        node->AddNode(new DataNode("backgroundImage", backgroundImage));
    }

    if(completeSave || !FieldsEqual(ID_imageRepeatX, &defaultObject))
    {
        addToParent = true;
        node->AddNode(new DataNode("imageRepeatX", imageRepeatX));
    }

    if(completeSave || !FieldsEqual(ID_imageRepeatY, &defaultObject))
    {
        addToParent = true;
        node->AddNode(new DataNode("imageRepeatY", imageRepeatY));
    }

    if(completeSave || !FieldsEqual(ID_axesArray, &defaultObject))
    {
        DataNode *axesArrayNode = new DataNode("axesArray");
        if(axesArray.CreateNode(axesArrayNode, completeSave, false))
        {
            addToParent = true;
            node->AddNode(axesArrayNode);
        }
        else
            delete axesArrayNode;
    }


    // Add the node to the parent node.
    if(addToParent || forceAdd)
        parentNode->AddNode(node);
    else
        delete node;

    return (addToParent || forceAdd);
}

// ****************************************************************************
// Method: AnnotationAttributes::SetFromNode
//
// Purpose:
//   This method sets attributes in this object from values in a DataNode representation of the object.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

void
AnnotationAttributes::SetFromNode(DataNode *parentNode)
{
    if(parentNode == 0)
        return;

    DataNode *searchNode = parentNode->GetNode("AnnotationAttributes");
    if(searchNode == 0)
        return;

    DataNode *node;
    if((node = searchNode->GetNode("axes2D")) != 0)
        axes2D.SetFromNode(node);
    if((node = searchNode->GetNode("axes3D")) != 0)
        axes3D.SetFromNode(node);
    if((node = searchNode->GetNode("userInfoFlag")) != 0)
        SetUserInfoFlag(node->AsBool());
    if((node = searchNode->GetNode("userInfoFont")) != 0)
        userInfoFont.SetFromNode(node);
    if((node = searchNode->GetNode("databaseInfoFlag")) != 0)
        SetDatabaseInfoFlag(node->AsBool());
    if((node = searchNode->GetNode("timeInfoFlag")) != 0)
        SetTimeInfoFlag(node->AsBool());
    if((node = searchNode->GetNode("databaseInfoFont")) != 0)
        databaseInfoFont.SetFromNode(node);
    if((node = searchNode->GetNode("databaseInfoExpansionMode")) != 0)
    {
        // Allow enums to be int or string in the config file
        if(node->GetNodeType() == INT_NODE)
        {
            int ival = node->AsInt();
            if(ival >= 0 && ival < 5)
                SetDatabaseInfoExpansionMode(PathExpansionMode(ival));
        }
        else if(node->GetNodeType() == STRING_NODE)
        {
            PathExpansionMode value;
            if(PathExpansionMode_FromString(node->AsString(), value))
                SetDatabaseInfoExpansionMode(value);
        }
    }
    if((node = searchNode->GetNode("databaseInfoTimeScale")) != 0)
        SetDatabaseInfoTimeScale(node->AsDouble());
    if((node = searchNode->GetNode("databaseInfoTimeOffset")) != 0)
        SetDatabaseInfoTimeOffset(node->AsDouble());
    if((node = searchNode->GetNode("legendInfoFlag")) != 0)
        SetLegendInfoFlag(node->AsBool());
    if((node = searchNode->GetNode("backgroundColor")) != 0)
        backgroundColor.SetFromNode(node);
    if((node = searchNode->GetNode("foregroundColor")) != 0)
        foregroundColor.SetFromNode(node);
    if((node = searchNode->GetNode("gradientBackgroundStyle")) != 0)
    {
        // Allow enums to be int or string in the config file
        if(node->GetNodeType() == INT_NODE)
        {
            int ival = node->AsInt();
            if(ival >= 0 && ival < 5)
                SetGradientBackgroundStyle(GradientStyle(ival));
        }
        else if(node->GetNodeType() == STRING_NODE)
        {
            GradientStyle value;
            if(GradientStyle_FromString(node->AsString(), value))
                SetGradientBackgroundStyle(value);
        }
    }
    if((node = searchNode->GetNode("gradientColor1")) != 0)
        gradientColor1.SetFromNode(node);
    if((node = searchNode->GetNode("gradientColor2")) != 0)
        gradientColor2.SetFromNode(node);
    if((node = searchNode->GetNode("backgroundMode")) != 0)
    {
        // Allow enums to be int or string in the config file
        if(node->GetNodeType() == INT_NODE)
        {
            int ival = node->AsInt();
            if(ival >= 0 && ival < 4)
                SetBackgroundMode(BackgroundMode(ival));
        }
        else if(node->GetNodeType() == STRING_NODE)
        {
            BackgroundMode value;
            if(BackgroundMode_FromString(node->AsString(), value))
                SetBackgroundMode(value);
        }
    }
    if((node = searchNode->GetNode("backgroundImage")) != 0)
        SetBackgroundImage(node->AsString());
    if((node = searchNode->GetNode("imageRepeatX")) != 0)
        SetImageRepeatX(node->AsInt());
    if((node = searchNode->GetNode("imageRepeatY")) != 0)
        SetImageRepeatY(node->AsInt());
    if((node = searchNode->GetNode("axesArray")) != 0)
        axesArray.SetFromNode(node);
}

///////////////////////////////////////////////////////////////////////////////
// Set property methods
///////////////////////////////////////////////////////////////////////////////

void
AnnotationAttributes::SetAxes2D(const Axes2D &axes2D_)
{
    axes2D = axes2D_;
    Select(ID_axes2D, (void *)&axes2D);
}

void
AnnotationAttributes::SetAxes3D(const Axes3D &axes3D_)
{
    axes3D = axes3D_;
    Select(ID_axes3D, (void *)&axes3D);
}

void
AnnotationAttributes::SetUserInfoFlag(bool userInfoFlag_)
{
    userInfoFlag = userInfoFlag_;
    Select(ID_userInfoFlag, (void *)&userInfoFlag);
}

void
AnnotationAttributes::SetUserInfoFont(const FontAttributes &userInfoFont_)
{
    userInfoFont = userInfoFont_;
    Select(ID_userInfoFont, (void *)&userInfoFont);
}

void
AnnotationAttributes::SetDatabaseInfoFlag(bool databaseInfoFlag_)
{
    databaseInfoFlag = databaseInfoFlag_;
    Select(ID_databaseInfoFlag, (void *)&databaseInfoFlag);
}

void
AnnotationAttributes::SetTimeInfoFlag(bool timeInfoFlag_)
{
    timeInfoFlag = timeInfoFlag_;
    Select(ID_timeInfoFlag, (void *)&timeInfoFlag);
}

void
AnnotationAttributes::SetDatabaseInfoFont(const FontAttributes &databaseInfoFont_)
{
    databaseInfoFont = databaseInfoFont_;
    Select(ID_databaseInfoFont, (void *)&databaseInfoFont);
}

void
AnnotationAttributes::SetDatabaseInfoExpansionMode(AnnotationAttributes::PathExpansionMode databaseInfoExpansionMode_)
{
    databaseInfoExpansionMode = databaseInfoExpansionMode_;
    Select(ID_databaseInfoExpansionMode, (void *)&databaseInfoExpansionMode);
}

void
AnnotationAttributes::SetDatabaseInfoTimeScale(double databaseInfoTimeScale_)
{
    databaseInfoTimeScale = databaseInfoTimeScale_;
    Select(ID_databaseInfoTimeScale, (void *)&databaseInfoTimeScale);
}

void
AnnotationAttributes::SetDatabaseInfoTimeOffset(double databaseInfoTimeOffset_)
{
    databaseInfoTimeOffset = databaseInfoTimeOffset_;
    Select(ID_databaseInfoTimeOffset, (void *)&databaseInfoTimeOffset);
}

void
AnnotationAttributes::SetLegendInfoFlag(bool legendInfoFlag_)
{
    legendInfoFlag = legendInfoFlag_;
    Select(ID_legendInfoFlag, (void *)&legendInfoFlag);
}

void
AnnotationAttributes::SetBackgroundColor(const ColorAttribute &backgroundColor_)
{
    backgroundColor = backgroundColor_;
    Select(ID_backgroundColor, (void *)&backgroundColor);
}

void
AnnotationAttributes::SetForegroundColor(const ColorAttribute &foregroundColor_)
{
    foregroundColor = foregroundColor_;
    Select(ID_foregroundColor, (void *)&foregroundColor);
}

void
AnnotationAttributes::SetGradientBackgroundStyle(AnnotationAttributes::GradientStyle gradientBackgroundStyle_)
{
    gradientBackgroundStyle = gradientBackgroundStyle_;
    Select(ID_gradientBackgroundStyle, (void *)&gradientBackgroundStyle);
}

void
AnnotationAttributes::SetGradientColor1(const ColorAttribute &gradientColor1_)
{
    gradientColor1 = gradientColor1_;
    Select(ID_gradientColor1, (void *)&gradientColor1);
}

void
AnnotationAttributes::SetGradientColor2(const ColorAttribute &gradientColor2_)
{
    gradientColor2 = gradientColor2_;
    Select(ID_gradientColor2, (void *)&gradientColor2);
}

void
AnnotationAttributes::SetBackgroundMode(AnnotationAttributes::BackgroundMode backgroundMode_)
{
    backgroundMode = backgroundMode_;
    Select(ID_backgroundMode, (void *)&backgroundMode);
}

void
AnnotationAttributes::SetBackgroundImage(const std::string &backgroundImage_)
{
    backgroundImage = backgroundImage_;
    Select(ID_backgroundImage, (void *)&backgroundImage);
}

void
AnnotationAttributes::SetImageRepeatX(int imageRepeatX_)
{
    imageRepeatX = imageRepeatX_;
    Select(ID_imageRepeatX, (void *)&imageRepeatX);
}

void
AnnotationAttributes::SetImageRepeatY(int imageRepeatY_)
{
    imageRepeatY = imageRepeatY_;
    Select(ID_imageRepeatY, (void *)&imageRepeatY);
}

void
AnnotationAttributes::SetAxesArray(const AxesArray &axesArray_)
{
    axesArray = axesArray_;
    Select(ID_axesArray, (void *)&axesArray);
}

///////////////////////////////////////////////////////////////////////////////
// Get property methods
///////////////////////////////////////////////////////////////////////////////

const Axes2D &
AnnotationAttributes::GetAxes2D() const
{
    return axes2D;
}

Axes2D &
AnnotationAttributes::GetAxes2D()
{
    return axes2D;
}

const Axes3D &
AnnotationAttributes::GetAxes3D() const
{
    return axes3D;
}

Axes3D &
AnnotationAttributes::GetAxes3D()
{
    return axes3D;
}

bool
AnnotationAttributes::GetUserInfoFlag() const
{
    return userInfoFlag;
}

const FontAttributes &
AnnotationAttributes::GetUserInfoFont() const
{
    return userInfoFont;
}

FontAttributes &
AnnotationAttributes::GetUserInfoFont()
{
    return userInfoFont;
}

bool
AnnotationAttributes::GetDatabaseInfoFlag() const
{
    return databaseInfoFlag;
}

bool
AnnotationAttributes::GetTimeInfoFlag() const
{
    return timeInfoFlag;
}

const FontAttributes &
AnnotationAttributes::GetDatabaseInfoFont() const
{
    return databaseInfoFont;
}

FontAttributes &
AnnotationAttributes::GetDatabaseInfoFont()
{
    return databaseInfoFont;
}

AnnotationAttributes::PathExpansionMode
AnnotationAttributes::GetDatabaseInfoExpansionMode() const
{
    return PathExpansionMode(databaseInfoExpansionMode);
}

double
AnnotationAttributes::GetDatabaseInfoTimeScale() const
{
    return databaseInfoTimeScale;
}

double
AnnotationAttributes::GetDatabaseInfoTimeOffset() const
{
    return databaseInfoTimeOffset;
}

bool
AnnotationAttributes::GetLegendInfoFlag() const
{
    return legendInfoFlag;
}

const ColorAttribute &
AnnotationAttributes::GetBackgroundColor() const
{
    return backgroundColor;
}

ColorAttribute &
AnnotationAttributes::GetBackgroundColor()
{
    return backgroundColor;
}

const ColorAttribute &
AnnotationAttributes::GetForegroundColor() const
{
    return foregroundColor;
}

ColorAttribute &
AnnotationAttributes::GetForegroundColor()
{
    return foregroundColor;
}

AnnotationAttributes::GradientStyle
AnnotationAttributes::GetGradientBackgroundStyle() const
{
    return GradientStyle(gradientBackgroundStyle);
}

const ColorAttribute &
AnnotationAttributes::GetGradientColor1() const
{
    return gradientColor1;
}

ColorAttribute &
AnnotationAttributes::GetGradientColor1()
{
    return gradientColor1;
}

const ColorAttribute &
AnnotationAttributes::GetGradientColor2() const
{
    return gradientColor2;
}

ColorAttribute &
AnnotationAttributes::GetGradientColor2()
{
    return gradientColor2;
}

AnnotationAttributes::BackgroundMode
AnnotationAttributes::GetBackgroundMode() const
{
    return BackgroundMode(backgroundMode);
}

const std::string &
AnnotationAttributes::GetBackgroundImage() const
{
    return backgroundImage;
}

std::string &
AnnotationAttributes::GetBackgroundImage()
{
    return backgroundImage;
}

int
AnnotationAttributes::GetImageRepeatX() const
{
    return imageRepeatX;
}

int
AnnotationAttributes::GetImageRepeatY() const
{
    return imageRepeatY;
}

const AxesArray &
AnnotationAttributes::GetAxesArray() const
{
    return axesArray;
}

AxesArray &
AnnotationAttributes::GetAxesArray()
{
    return axesArray;
}

///////////////////////////////////////////////////////////////////////////////
// Select property methods
///////////////////////////////////////////////////////////////////////////////

void
AnnotationAttributes::SelectAxes2D()
{
    Select(ID_axes2D, (void *)&axes2D);
}

void
AnnotationAttributes::SelectAxes3D()
{
    Select(ID_axes3D, (void *)&axes3D);
}

void
AnnotationAttributes::SelectUserInfoFont()
{
    Select(ID_userInfoFont, (void *)&userInfoFont);
}

void
AnnotationAttributes::SelectDatabaseInfoFont()
{
    Select(ID_databaseInfoFont, (void *)&databaseInfoFont);
}

void
AnnotationAttributes::SelectBackgroundColor()
{
    Select(ID_backgroundColor, (void *)&backgroundColor);
}

void
AnnotationAttributes::SelectForegroundColor()
{
    Select(ID_foregroundColor, (void *)&foregroundColor);
}

void
AnnotationAttributes::SelectGradientColor1()
{
    Select(ID_gradientColor1, (void *)&gradientColor1);
}

void
AnnotationAttributes::SelectGradientColor2()
{
    Select(ID_gradientColor2, (void *)&gradientColor2);
}

void
AnnotationAttributes::SelectBackgroundImage()
{
    Select(ID_backgroundImage, (void *)&backgroundImage);
}

void
AnnotationAttributes::SelectAxesArray()
{
    Select(ID_axesArray, (void *)&axesArray);
}

///////////////////////////////////////////////////////////////////////////////
// Keyframing methods
///////////////////////////////////////////////////////////////////////////////

// ****************************************************************************
// Method: AnnotationAttributes::GetFieldName
//
// Purpose:
//   This method returns the name of a field given its index.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

std::string
AnnotationAttributes::GetFieldName(int index) const
{
    switch (index)
    {
    case ID_axes2D:                    return "axes2D";
    case ID_axes3D:                    return "axes3D";
    case ID_userInfoFlag:              return "userInfoFlag";
    case ID_userInfoFont:              return "userInfoFont";
    case ID_databaseInfoFlag:          return "databaseInfoFlag";
    case ID_timeInfoFlag:              return "timeInfoFlag";
    case ID_databaseInfoFont:          return "databaseInfoFont";
    case ID_databaseInfoExpansionMode: return "databaseInfoExpansionMode";
    case ID_databaseInfoTimeScale:     return "databaseInfoTimeScale";
    case ID_databaseInfoTimeOffset:    return "databaseInfoTimeOffset";
    case ID_legendInfoFlag:            return "legendInfoFlag";
    case ID_backgroundColor:           return "backgroundColor";
    case ID_foregroundColor:           return "foregroundColor";
    case ID_gradientBackgroundStyle:   return "gradientBackgroundStyle";
    case ID_gradientColor1:            return "gradientColor1";
    case ID_gradientColor2:            return "gradientColor2";
    case ID_backgroundMode:            return "backgroundMode";
    case ID_backgroundImage:           return "backgroundImage";
    case ID_imageRepeatX:              return "imageRepeatX";
    case ID_imageRepeatY:              return "imageRepeatY";
    case ID_axesArray:                 return "axesArray";
    default:  return "invalid index";
    }
}

// ****************************************************************************
// Method: AnnotationAttributes::GetFieldType
//
// Purpose:
//   This method returns the type of a field given its index.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

AttributeGroup::FieldType
AnnotationAttributes::GetFieldType(int index) const
{
    switch (index)
    {
    case ID_axes2D:                    return FieldType_att;
    case ID_axes3D:                    return FieldType_att;
    case ID_userInfoFlag:              return FieldType_bool;
    case ID_userInfoFont:              return FieldType_att;
    case ID_databaseInfoFlag:          return FieldType_bool;
    case ID_timeInfoFlag:              return FieldType_bool;
    case ID_databaseInfoFont:          return FieldType_att;
    case ID_databaseInfoExpansionMode: return FieldType_enum;
    case ID_databaseInfoTimeScale:     return FieldType_double;
    case ID_databaseInfoTimeOffset:    return FieldType_double;
    case ID_legendInfoFlag:            return FieldType_bool;
    case ID_backgroundColor:           return FieldType_color;
    case ID_foregroundColor:           return FieldType_color;
    case ID_gradientBackgroundStyle:   return FieldType_enum;
    case ID_gradientColor1:            return FieldType_color;
    case ID_gradientColor2:            return FieldType_color;
    case ID_backgroundMode:            return FieldType_enum;
    case ID_backgroundImage:           return FieldType_string;
    case ID_imageRepeatX:              return FieldType_int;
    case ID_imageRepeatY:              return FieldType_int;
    case ID_axesArray:                 return FieldType_att;
    default:  return FieldType_unknown;
    }
}

// ****************************************************************************
// Method: AnnotationAttributes::GetFieldTypeName
//
// Purpose:
//   This method returns the name of a field type given its index.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

std::string
AnnotationAttributes::GetFieldTypeName(int index) const
{
    switch (index)
    {
    case ID_axes2D:                    return "att";
    case ID_axes3D:                    return "att";
    case ID_userInfoFlag:              return "bool";
    case ID_userInfoFont:              return "att";
    case ID_databaseInfoFlag:          return "bool";
    case ID_timeInfoFlag:              return "bool";
    case ID_databaseInfoFont:          return "att";
    case ID_databaseInfoExpansionMode: return "enum";
    case ID_databaseInfoTimeScale:     return "double";
    case ID_databaseInfoTimeOffset:    return "double";
    case ID_legendInfoFlag:            return "bool";
    case ID_backgroundColor:           return "color";
    case ID_foregroundColor:           return "color";
    case ID_gradientBackgroundStyle:   return "enum";
    case ID_gradientColor1:            return "color";
    case ID_gradientColor2:            return "color";
    case ID_backgroundMode:            return "enum";
    case ID_backgroundImage:           return "string";
    case ID_imageRepeatX:              return "int";
    case ID_imageRepeatY:              return "int";
    case ID_axesArray:                 return "att";
    default:  return "invalid index";
    }
}

// ****************************************************************************
// Method: AnnotationAttributes::FieldsEqual
//
// Purpose:
//   This method compares two fields and return true if they are equal.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

bool
AnnotationAttributes::FieldsEqual(int index_, const AttributeGroup *rhs) const
{
    const AnnotationAttributes &obj = *((const AnnotationAttributes*)rhs);
    bool retval = false;
    switch (index_)
    {
    case ID_axes2D:
        {  // new scope
        retval = (axes2D == obj.axes2D);
        }
        break;
    case ID_axes3D:
        {  // new scope
        retval = (axes3D == obj.axes3D);
        }
        break;
    case ID_userInfoFlag:
        {  // new scope
        retval = (userInfoFlag == obj.userInfoFlag);
        }
        break;
    case ID_userInfoFont:
        {  // new scope
        retval = (userInfoFont == obj.userInfoFont);
        }
        break;
    case ID_databaseInfoFlag:
        {  // new scope
        retval = (databaseInfoFlag == obj.databaseInfoFlag);
        }
        break;
    case ID_timeInfoFlag:
        {  // new scope
        retval = (timeInfoFlag == obj.timeInfoFlag);
        }
        break;
    case ID_databaseInfoFont:
        {  // new scope
        retval = (databaseInfoFont == obj.databaseInfoFont);
        }
        break;
    case ID_databaseInfoExpansionMode:
        {  // new scope
        retval = (databaseInfoExpansionMode == obj.databaseInfoExpansionMode);
        }
        break;
    case ID_databaseInfoTimeScale:
        {  // new scope
        retval = (databaseInfoTimeScale == obj.databaseInfoTimeScale);
        }
        break;
    case ID_databaseInfoTimeOffset:
        {  // new scope
        retval = (databaseInfoTimeOffset == obj.databaseInfoTimeOffset);
        }
        break;
    case ID_legendInfoFlag:
        {  // new scope
        retval = (legendInfoFlag == obj.legendInfoFlag);
        }
        break;
    case ID_backgroundColor:
        {  // new scope
        retval = (backgroundColor == obj.backgroundColor);
        }
        break;
    case ID_foregroundColor:
        {  // new scope
        retval = (foregroundColor == obj.foregroundColor);
        }
        break;
    case ID_gradientBackgroundStyle:
        {  // new scope
        retval = (gradientBackgroundStyle == obj.gradientBackgroundStyle);
        }
        break;
    case ID_gradientColor1:
        {  // new scope
        retval = (gradientColor1 == obj.gradientColor1);
        }
        break;
    case ID_gradientColor2:
        {  // new scope
        retval = (gradientColor2 == obj.gradientColor2);
        }
        break;
    case ID_backgroundMode:
        {  // new scope
        retval = (backgroundMode == obj.backgroundMode);
        }
        break;
    case ID_backgroundImage:
        {  // new scope
        retval = (backgroundImage == obj.backgroundImage);
        }
        break;
    case ID_imageRepeatX:
        {  // new scope
        retval = (imageRepeatX == obj.imageRepeatX);
        }
        break;
    case ID_imageRepeatY:
        {  // new scope
        retval = (imageRepeatY == obj.imageRepeatY);
        }
        break;
    case ID_axesArray:
        {  // new scope
        retval = (axesArray == obj.axesArray);
        }
        break;
    default: retval = false;
    }

    return retval;
}

///////////////////////////////////////////////////////////////////////////////
// User-defined methods.
///////////////////////////////////////////////////////////////////////////////

// Returns a "discernible" background color. If the background mode
// is Solid, the returned value is just the background color. If the
// background mode is Gradient, the returned color is an average of
// the two gradient colors
const ColorAttribute AnnotationAttributes::GetDiscernibleBackgroundColor() const
{
    ColorAttribute retval;
    double bg[4];

    if (GetBackgroundMode() == Solid)
    {
        GetBackgroundColor().GetRgba(bg);
    }
    else
    {
        double gbg1[4], gbg2[4];

        GetGradientColor1().GetRgba(gbg1);
        GetGradientColor2().GetRgba(gbg2);

        bg[0] = (gbg1[0] + gbg2[0]) * 0.5;
        bg[1] = (gbg1[1] + gbg2[1]) * 0.5;
        bg[2] = (gbg1[2] + gbg2[2]) * 0.5;
        bg[3] = (gbg1[3] + gbg2[3]) * 0.5;
    }

    retval.SetRgba2(bg);

    return retval;
}

